package com.neolix.watch.bluetooth;

import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.neolix.watch.util.Constant;

import java.util.UUID;

import static com.neolix.watch.bluetooth.SampleGattAttributes.getStepsUUID;
import static com.neolix.watch.bluetooth.SampleGattAttributes.syncActiveUUID;
import static com.neolix.watch.bluetooth.SampleGattAttributes.syncActivatedUUID;
import static com.neolix.watch.bluetooth.SampleGattAttributes.syncBluetoothNameUUID;
import static com.neolix.watch.bluetooth.SampleGattAttributes.syncDateTimeUUID;
import static com.neolix.watch.bluetooth.SampleGattAttributes.syncNotificationUUID;
import static com.neolix.watch.bluetooth.SampleGattAttributes.syncRemindEventUUID;
import static com.neolix.watch.bluetooth.SampleGattAttributes.syncWatchStyleUUID;
import static com.neolix.watch.bluetooth.SampleGattAttributes.syncWeatherUUID;
import static com.neolix.watch.bluetooth.SampleGattAttributes.unKnowUUID;
import static com.neolix.watch.bluetooth.SampleGattAttributes.watchServiceUUID;
import static java.util.Arrays.asList;

public enum WatchCommandType {
    UNKNOWN(UUID.fromString(unKnowUUID), UUID.fromString(unKnowUUID)) {
        @Override
        String getReadAction() {
            return "";
        }

        @Override
        String getWriteAction() {
            return "";
        }
    },
    syncDateTime(UUID.fromString(watchServiceUUID), UUID.fromString(syncDateTimeUUID)) {
        @Override
        String getReadAction() {
            return Constant.WatchAction.ACTION_WATCH_READ_SYNC_DATE_TIME;
        }

        @Override
        String getWriteAction() {
            return Constant.WatchAction.ACTION_WATCH_WRITE_SYNC_DATE_TIME;
        }
    },
    syncSteps(UUID.fromString(watchServiceUUID), UUID.fromString(getStepsUUID)) {
        @Override
        String getReadAction() {
            return Constant.WatchAction.ACTION_WATCH_READ_GET_STEPS;
        }

        @Override
        String getWriteAction() {
            return Constant.WatchAction.ACTION_WATCH_WRITE_STEPS;
        }
    }, syncRemindEvent(UUID.fromString(watchServiceUUID), UUID.fromString(syncRemindEventUUID)) {
        @Override
        String getReadAction() {
            return Constant.WatchAction.ACTION_WATCH_READ_SYNC_REMIND_EVENT;
        }

        @Override
        String getWriteAction() {
            return Constant.WatchAction.ACTION_WATCH_WRITE_SYNC_REMIND_EVENT;
        }
    }, syncNotification(UUID.fromString(watchServiceUUID), UUID.fromString(syncNotificationUUID)) {
        @Override
        String getReadAction() {
            return Constant.WatchAction.ACTION_WATCH_READ_SYNC_Notification;
        }

        @Override
        String getWriteAction() {
            return Constant.WatchAction.ACTION_WATCH_WRITE_SYNC_Notification;
        }
    },

    syncWeather(UUID.fromString(watchServiceUUID), UUID.fromString(syncWeatherUUID)) {
        @Override
        String getReadAction() {
            return Constant.WatchAction.ACTION_WATCH_READ_SYNC_WEATHER;
        }

        @Override
        String getWriteAction() {
            return Constant.WatchAction.ACTION_WATCH_WRITE_SYNC_WEATHER;
        }
    }, syncWatchStyle(UUID.fromString(watchServiceUUID), UUID.fromString(syncWatchStyleUUID)) {
        @Override
        String getReadAction() {
            return Constant.WatchAction.ACTION_WATCH_READ_WATCH_STYLE;
        }

        @Override
        String getWriteAction() {
            return Constant.WatchAction.ACTION_WATCH_WRITE_WATCH_STYLE;
        }
    }, syncActive(UUID.fromString(watchServiceUUID), UUID.fromString(syncActiveUUID)) {
        //激活手表
        @Override
        String getReadAction() {
            return Constant.WatchAction.ACTION_WATCH_READ_ACTIVE;
        }

        @Override
        String getWriteAction() {
            return Constant.WatchAction.ACTION_WATCH_WRITE_ACTIVE;
        }
    }, syncActivated(UUID.fromString(watchServiceUUID), UUID.fromString(syncActivatedUUID)) {
        //被手表激活
        @Override
        String getReadAction() {
            return Constant.WatchAction.ACTION_WATCH_READ_ACTIVATED;
        }

        @Override
        String getWriteAction() {
            return Constant.WatchAction.ACTION_WATCH_WRITE_ACTIVATED;
        }
    }, syncBluetoothName(UUID.fromString(watchServiceUUID), UUID.fromString(syncBluetoothNameUUID)) {
        //告知手表本地蓝牙的名称
        @Override
        String getReadAction() {
            return Constant.WatchAction.ACTION_WATCH_READ_BLUETOOTH_NAME;
        }

        @Override
        String getWriteAction() {
            return Constant.WatchAction.ACTION_WATCH_WRITE_BLUETOOTH_NAME;
        }
    };

    private UUID serviceUUID;
    private UUID characteristicUUDI;

    public UUID getCharacteristicUUID() {
        return characteristicUUDI;
    }

    public UUID getServiceUUID() {
        return serviceUUID;
    }

    private WatchCommandType(UUID serviceUUID, UUID characteristicUUDI) {
        this.serviceUUID = serviceUUID;
        this.characteristicUUDI = characteristicUUDI;
    }

    abstract String getReadAction();

    abstract String getWriteAction();

    public static WatchCommandType findCommandType(final UUID characteristicUUDI) {
        Optional<WatchCommandType> orderTypeOptional = Iterables.tryFind(asList(WatchCommandType.values()), new Predicate<WatchCommandType>() {
            @Override
            public boolean apply(WatchCommandType orderType) {
                return orderType.getCharacteristicUUID().toString().equals(characteristicUUDI.toString());
            }
        });

        return orderTypeOptional.isPresent() ? orderTypeOptional.get() : UNKNOWN;
    }

    public static String getReadAction(final UUID characteristicUUDI) {
        WatchCommandType watchCommandType = findCommandType(characteristicUUDI);
        return watchCommandType.getReadAction();
    }

    public static String getWriteAction(final UUID characteristicUUDI) {
        WatchCommandType watchCommandType = findCommandType(characteristicUUDI);
        return watchCommandType.getWriteAction();
    }
}
